﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Broker.Model;
using RabbitMQ.Client;
using Broker.Downstream.Properties;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Broker.Downstream
{
    public class StockConnection
    {
        public delegate void StockUpdatedHandler(object sender, StockUpdatedEventArgs e);

        public event StockUpdatedHandler StockUpdated;

        public String ServerAddress { get; private set; }

        public StockConnection(String serverAddress)
        {
            ServerAddress = serverAddress;
        }

        public void Listen()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.Uri = ServerAddress;

            using (IConnection connection = factory.CreateConnection())
            {
                using (IModel model = connection.CreateModel())
                {
                    Dictionary<String, Object> args = new Dictionary<String, Object>();
                    args.Add("type", "fanout");
                    args.Add("upstream-set", Settings.Default.UpstreamSetName);
                    model.ExchangeDeclare(Settings.Default.ExchangeName, "x-federation", true, false, args);
                    String queueName = String.Format("{0}-queue", Settings.Default.ExchangeName);
                    model.QueueDeclare(queueName, true, false, false, null);
                    model.QueueBind(queueName, Settings.Default.ExchangeName, String.Empty);

                    while (true)
                    {
                        BasicGetResult result = model.BasicGet(queueName, true);
                        if (result != null)
                        {
                            MemoryStream memStream = new MemoryStream(result.Body);
                            BinaryFormatter formatter = new BinaryFormatter();
                            object stockObj = formatter.Deserialize(memStream);
                            if (StockUpdated != null)
                            {
                                StockUpdated(this, new StockUpdatedEventArgs(stockObj as Stock));
                            }
                        }
                    }
                }
            }
        }
    }
}
